package platform

import (
	"encoding/json"
	"net/http"
	"strconv"

	"gitee.com/wangshh_123/cross-pay-go/src/database"
	"gitee.com/wangshh_123/cross-pay-go/src/errors"
	"gitee.com/wangshh_123/cross-pay-go/src/middleware"
	"gitee.com/wangshh_123/cross-pay-go/src/models"
	"gitee.com/wangshh_123/cross-pay-go/src/service"
	"gitee.com/wangshh_123/cross-pay-go/src/utils/auth"
	commonUtils "gitee.com/wangshh_123/cross-pay-go/src/utils/common"
	"github.com/gin-gonic/gin"
	"github.com/shopspring/decimal"
	"gorm.io/gorm"
)

// HlPayAccountBalanceController HlPay账户余额控制器
type HlPayAccountBalanceController struct {
	accountBalanceService *service.HlPayAccountBalanceService
	db                    *gorm.DB
}

// NewHlPayAccountBalanceController 创建HlPay账户余额控制器
func NewHlPayAccountBalanceController() *HlPayAccountBalanceController {
	return &HlPayAccountBalanceController{
		accountBalanceService: service.NewHlPayAccountBalanceService(),
		db:                    database.DB,
	}
}

// getUserRoleAndBalance 获取用户角色和余额信息
func (c *HlPayAccountBalanceController) getUserRoleAndBalance(ctx *gin.Context) (*UserRoleBalance, error) {
	claims, exists := ctx.Get("claims")
	if !exists {
		return nil, errors.NewAppError(http.StatusUnauthorized, "unauthorized", nil)
	}
	authClaims, ok := claims.(*auth.Claims)
	if !ok {
		return nil, errors.NewAppError(http.StatusInternalServerError, "invalid_token_claims", nil)
	}

	userID := authClaims.UserID
	roleID := authClaims.RoleID
	var balance decimal.Decimal

	// 简化余额获取逻辑，根据角色返回不同的余额
	switch roleID {
	case 2: // 普通用户 - 返回0余额
		balance = decimal.Zero
	case 3: // 主账号 - 从主账号表获取余额
		var masterAccount models.MasterAccount
		if err := c.db.Where("user_id = ?", userID).First(&masterAccount).Error; err != nil {
			// 如果查询失败，返回0余额
			balance = decimal.Zero
		} else {
			balance = masterAccount.Balance
		}
	case 5: // 子账号 - 从子账号表获取余额
		var subAccount models.SubAccount
		if err := c.db.Where("user_id = ?", userID).First(&subAccount).Error; err != nil {
			// 如果查询失败，返回0余额
			balance = decimal.Zero
		} else {
			balance = subAccount.Balance
		}
	default:
		balance = decimal.Zero
	}

	return &UserRoleBalance{
		RoleID:  roleID,
		UserID:  userID,
		Balance: balance,
	}, nil
}

// getMatrixAccountFromToken 从token中获取matrixAccount信息
func (c *HlPayAccountBalanceController) getMatrixAccountFromToken(ctx *gin.Context) (*models.MatrixAccountInfo, error) {
	matrixAccountInfo, exists := ctx.Get("matrix_account_info")
	if !exists {
		return nil, errors.NewAppError(http.StatusUnauthorized, "matrix_account_info_not_found", nil)
	}

	matrixAccount, ok := matrixAccountInfo.(*models.UserMatrixAccount)
	if !ok {
		return nil, errors.NewAppError(http.StatusInternalServerError, "invalid_matrix_account_info", nil)
	}

	return &models.MatrixAccountInfo{
		UserID:            matrixAccount.UserID,
		MatrixAccount:     matrixAccount.MatrixAccount,
		MatrixAccountName: matrixAccount.MatrixAccountName,
	}, nil
}

// GetAccountBalances 获取账户余额列表（适配 PhotonPay 格式）
func (c *HlPayAccountBalanceController) GetAccountBalances(ctx *gin.Context) {
	// 获取用户角色和余额信息
	userInfo, err := c.getUserRoleAndBalance(ctx)
	if err != nil {
		commonUtils.Error(ctx, err.(*errors.AppError).Code, err.Error(), nil)
		return
	}

	// 获取矩阵账户信息
	matrixAccountInfo, err := c.getMatrixAccountFromToken(ctx)
	if err != nil {
		commonUtils.Error(ctx, err.(*errors.AppError).Code, err.Error(), nil)
		return
	}

	// 获取分页参数
	pageIndex, _ := strconv.ParseInt(ctx.DefaultQuery("pageIndex", "1"), 10, 64)
	pageSize, _ := strconv.ParseInt(ctx.DefaultQuery("pageSize", "10"), 10, 64)

	// 调用服务获取账户余额列表
	result, err := c.accountBalanceService.GetAccountBalancesByMatrixAccount(ctx, matrixAccountInfo.MatrixAccount, pageIndex, pageSize)
	if err != nil {
		commonUtils.Error(ctx, http.StatusInternalServerError, "get_account_balances_failed", err)
		return
	}

	// 结构体转 map，合并本地字段
	var respMap map[string]interface{}
	b, _ := json.Marshal(result)
	json.Unmarshal(b, &respMap)
	respMap["roleId"] = userInfo.RoleID

	// 查总转入
	var totalTransferAmount float64
	_ = c.db.Model(&models.UserMatrixAccount{}).
		Where("matrix_account = ?", matrixAccountInfo.MatrixAccount).
		Select("TotalTransferAmount").
		Scan(&totalTransferAmount)
	respMap["totalTransferAmount"] = totalTransferAmount

	// 根据角色设置本地余额
	respMap["localBalance"] = userInfo.Balance.InexactFloat64()

	// 如果是角色3或5，替换USD账户的realTimeBalance为localBalance
	if userInfo.RoleID == 3 || userInfo.RoleID == 5 {
		if data, ok := respMap["data"].([]interface{}); ok {
			for i, account := range data {
				if accountMap, ok := account.(map[string]interface{}); ok {
					if currency, ok := accountMap["currency"].(string); ok && currency == "USD" {
						// 保存原始的realTimeBalance
						accountMap["originalRealTimeBalance"] = accountMap["realTimeBalance"]
						// 替换为localBalance
						accountMap["realTimeBalance"] = userInfo.Balance.InexactFloat64()
						// 更新回数组
						data[i] = accountMap
					}
				}
			}
			respMap["data"] = data
		}
	}

	commonUtils.Success(ctx, respMap)
}

// GetAccountBalanceByAccountNo 根据账户号获取账户余额
func (c *HlPayAccountBalanceController) GetAccountBalanceByAccountNo(ctx *gin.Context) {
	// 获取账户号参数
	accountNo := ctx.Param("accountNo")
	if accountNo == "" {
		commonUtils.Error(ctx, http.StatusBadRequest, "account_no_required", nil)
		return
	}

	// 调用服务获取账户余额
	balance, err := c.accountBalanceService.GetAccountBalanceByAccountNo(ctx, accountNo)
	if err != nil {
		commonUtils.Error(ctx, http.StatusInternalServerError, "get_account_balance_failed", err)
		return
	}

	// 返回成功响应
	commonUtils.Success(ctx, gin.H{
		"code": "200",
		"msg": gin.H{
			"CN": "操作成功",
			"EN": "Operation successful",
			"VN": "Thao tác thành công",
		},
		"data": balance,
	})
}

// GetTotalBalance 获取总余额
func (c *HlPayAccountBalanceController) GetTotalBalance(ctx *gin.Context) {
	// 获取用户角色和余额信息
	userInfo, err := c.getUserRoleAndBalance(ctx)
	if err != nil {
		commonUtils.Error(ctx, err.(*errors.AppError).Code, err.Error(), nil)
		return
	}

	// 获取矩阵账户信息
	matrixAccountInfo, err := c.getMatrixAccountFromToken(ctx)
	if err != nil {
		commonUtils.Error(ctx, err.(*errors.AppError).Code, err.Error(), nil)
		return
	}

	// 调用服务获取总余额
	totalBalance, err := c.accountBalanceService.GetTotalBalanceByMatrixAccount(ctx, matrixAccountInfo.MatrixAccount)
	if err != nil {
		commonUtils.Error(ctx, http.StatusInternalServerError, "get_total_balance_failed", err)
		return
	}

	// 转换为float64
	totalBalanceFloat, _ := totalBalance.Float64()

	// 返回成功响应
	commonUtils.Success(ctx, gin.H{
		"code": "200",
		"msg": gin.H{
			"CN": "操作成功",
			"EN": "Operation successful",
			"VN": "Thao tác thành công",
		},
		"data": gin.H{
			"totalBalance": totalBalanceFloat,
			"localBalance": userInfo.Balance.InexactFloat64(),
			"currency":     "USD",
			"roleId":       userInfo.RoleID,
		},
	})
}

// DebugPlatformInfo 调试平台信息（临时接口，用于排查问题）
func (c *HlPayAccountBalanceController) DebugPlatformInfo(ctx *gin.Context) {
	// 获取用户ID
	userID, exists := ctx.Get("user_id")
	if !exists {
		commonUtils.Error(ctx, http.StatusUnauthorized, "user_id_not_found", nil)
		return
	}

	// 获取矩阵账户信息
	matrixAccount, exists := middleware.GetMatrixAccountFromContext(ctx)
	if !exists {
		commonUtils.Error(ctx, http.StatusUnauthorized, "matrix_account_not_found", nil)
		return
	}

	// 获取平台信息
	platformInfo, exists := middleware.GetPlatformInfoFromContext(ctx)
	if !exists {
		commonUtils.Error(ctx, http.StatusUnauthorized, "platform_info_not_found", nil)
		return
	}

	// 返回调试信息
	commonUtils.Success(ctx, gin.H{
		"code": "200",
		"msg": gin.H{
			"CN": "调试信息",
			"EN": "Debug information",
			"VN": "Thông tin debug",
		},
		"data": gin.H{
			"user_id":        userID,
			"matrix_account": matrixAccount,
			"platform_info":  platformInfo,
		},
	})
}

// TestSimpleEndpoint 简单测试接口（不需要平台信息中间件）
func (c *HlPayAccountBalanceController) TestSimpleEndpoint(ctx *gin.Context) {
	// 获取用户ID
	userID, exists := ctx.Get("user_id")
	if !exists {
		commonUtils.Error(ctx, http.StatusUnauthorized, "user_id_not_found", nil)
		return
	}

	// 返回简单测试信息
	commonUtils.Success(ctx, gin.H{
		"code": "200",
		"msg": gin.H{
			"CN": "测试成功",
			"EN": "Test successful",
			"VN": "Thử nghiệm thành công",
		},
		"data": gin.H{
			"user_id": userID,
			"message": "Simple test endpoint works!",
		},
	})
}

// GetAccountList 获取账户列表（适配 PhotonPay 格式）
func (c *HlPayAccountBalanceController) GetAccountList(ctx *gin.Context) {
	// 获取用户角色和余额信息
	userInfo, err := c.getUserRoleAndBalance(ctx)
	if err != nil {
		commonUtils.Error(ctx, err.(*errors.AppError).Code, err.Error(), nil)
		return
	}

	// 获取矩阵账户信息
	matrixAccountInfo, err := c.getMatrixAccountFromToken(ctx)
	if err != nil {
		commonUtils.Error(ctx, err.(*errors.AppError).Code, err.Error(), nil)
		return
	}

	// 获取分页参数
	pageIndex, _ := strconv.ParseInt(ctx.DefaultQuery("pageIndex", "1"), 10, 64)
	pageSize, _ := strconv.ParseInt(ctx.DefaultQuery("pageSize", "10"), 10, 64)

	// 调用服务获取账户余额列表
	result, err := c.accountBalanceService.GetAccountBalancesByMatrixAccount(ctx, matrixAccountInfo.MatrixAccount, pageIndex, pageSize)
	if err != nil {
		commonUtils.Error(ctx, http.StatusInternalServerError, "get_account_list_failed", err)
		return
	}

	// 结构体转 map，合并本地字段
	var respMap map[string]interface{}
	b, _ := json.Marshal(result)
	json.Unmarshal(b, &respMap)
	respMap["roleId"] = userInfo.RoleID

	// 查总转入
	var totalTransferAmount float64
	_ = c.db.Model(&models.UserMatrixAccount{}).
		Where("matrix_account = ?", matrixAccountInfo.MatrixAccount).
		Select("TotalTransferAmount").
		Scan(&totalTransferAmount)
	respMap["totalTransferAmount"] = totalTransferAmount

	// 根据角色设置本地余额
	respMap["localBalance"] = userInfo.Balance.InexactFloat64()

	// 如果是角色3或5，替换USD账户的realTimeBalance为localBalance
	if userInfo.RoleID == 3 || userInfo.RoleID == 5 {
		if data, ok := respMap["data"].([]interface{}); ok {
			for i, account := range data {
				if accountMap, ok := account.(map[string]interface{}); ok {
					if currency, ok := accountMap["currency"].(string); ok && currency == "USD" {
						// 保存原始的realTimeBalance
						accountMap["originalRealTimeBalance"] = accountMap["realTimeBalance"]
						// 替换为localBalance
						accountMap["realTimeBalance"] = userInfo.Balance.InexactFloat64()
						// 更新回数组
						data[i] = accountMap
					}
				}
			}
			respMap["data"] = data
		}
	}

	commonUtils.Success(ctx, respMap)
}
